package com.smart.community.property.controller;

import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.Result;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.property.dto.PropertyInfoDTO;
import com.smart.community.property.service.IPropertyInfoService;
import com.smart.community.commons.vo.property.PropertyInfoVO;
import com.smart.community.property.vo.PropertyInfoStatsVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;

/**
 * 物业信息管理控制器
 * 提供物业公司信息查看、编辑、统计等功能的REST API接口
 * 
 * 严格按照《Java后端SpringBoot代码开发规范.md》Controller层规范实现：
 * - 路径规范：以模块名开头，不使用/api前缀
 * - 异常处理：完善的try-catch块，区分业务异常(WARN)和系统异常(ERROR)
 * - 日志记录：统一的日志格式，提升可读性和可维护性
 * - 参数验证：完善的参数验证和错误提示
 * - 接口调用：调用Service接口，不直接调用实现类
 * - 职责单一：Controller只负责请求处理和响应封装，不包含复杂业务逻辑
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 * @version 1.0.4 - 严格按照Controller规范调整，完善异常处理和参数验证
 */
@Slf4j
@RestController
@RequestMapping("/property/info")
@RequiredArgsConstructor
@Tag(name = "物业信息管理", description = "物业公司信息管理相关接口")
@Validated
public class PropertyInfoController {

    private final IPropertyInfoService propertyInfoService;

    /**
     * 检查当前用户是否有关联的物业公司
     * 此接口必须在通配符路径之前定义，避免路径冲突
     * 
     * @return 是否有关联的物业公司
     * @throws Exception 统一异常
     */
    @GetMapping("/has-company")
    @Operation(summary = "检查物业公司关联", description = "检查当前登录用户是否有关联的物业公司")
    public Result<Boolean> hasPropertyCompany() throws Exception {
        log.info("开始检查当前用户物业公司关联状态");
        
        // 权限验证
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            log.warn("用户未登录，无法检查物业公司关联状态");
            return Result.fail("用户未登录，请先登录");
        }
        
        // 调用Service层检查物业公司关联
        // 严格按照Controller规范：Controller只负责请求处理和响应封装，不包含复杂业务逻辑
        boolean hasProperty = propertyInfoService.hasPropertyCompany(currentUserId);
        
        log.info("用户{}物业公司关联状态检查完成，结果：{}", currentUserId, hasProperty);
        return Result.success(hasProperty);
    }

    /**
     * 获取物业公司信息
     * 注意：此接口使用通配符路径，必须在具体路径之后定义
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 物业公司信息
     * @throws Exception 统一异常
     */
    @GetMapping("/{propertyCompanyId}")
    @Operation(summary = "获取物业公司信息", description = "根据物业公司ID获取详细信息")
    public Result<PropertyInfoVO> getPropertyInfo(
            @Parameter(description = "物业公司ID", required = true)
            @PathVariable @NotNull(message = "物业公司ID不能为空") 
            @Positive(message = "物业公司ID必须为正数") Long propertyCompanyId) throws Exception {
        log.info("开始获取物业公司信息，物业公司ID：{}", propertyCompanyId);
        
        // 权限验证
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            log.warn("用户未登录，无法获取物业公司{}信息", propertyCompanyId);
            return Result.fail("用户未登录，请先登录");
        }
        
        // 调用Service层获取物业公司信息
        PropertyInfoVO propertyInfo = propertyInfoService.getPropertyInfo(propertyCompanyId);
        
        if (propertyInfo != null) {
            log.info("物业公司{}信息获取成功", propertyCompanyId);
            return Result.success(propertyInfo);
        } else {
            log.warn("物业公司{}信息不存在", propertyCompanyId);
            return Result.fail("物业公司信息不存在");
        }
    }


    /**
     * 获取物业公司综合统计信息
     * 
     * 注意：此接口专门用于获取物业信息服务特有的统计信息
     * 核心统计数据（总服务面积、服务社区、服务户数）通过调用统计服务获取
     * 避免与统计服务功能重复，保持职责分离
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 统计信息（包含核心统计+物业特有数据）
     * @throws Exception 统一异常
     */
    @GetMapping("/stats/{propertyCompanyId}")
    @Operation(summary = "获取物业公司综合统计信息", description = "获取物业公司统计信息，包含核心统计数据（总服务面积、服务社区、服务户数）和物业特有数据（服务质量、月收入、月支出、利润率）")
    public Result<PropertyInfoStatsVO> getPropertyInfoStats(
            @Parameter(description = "物业公司ID", required = true)
            @PathVariable @NotNull(message = "物业公司ID不能为空") 
            @Positive(message = "物业公司ID必须为正数") Long propertyCompanyId) throws Exception {
        log.info("开始获取物业公司{}综合统计信息", propertyCompanyId);
        
        // 权限验证
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            log.warn("用户未登录，无法获取物业公司{}统计信息", propertyCompanyId);
            return Result.fail("用户未登录，请先登录");
        }
        
        // 调用Service层获取统计信息
        // 严格按照Controller规范：Controller只负责请求处理和响应封装，不包含复杂业务逻辑
        PropertyInfoStatsVO stats = propertyInfoService.getPropertyInfoStats(propertyCompanyId);
        
        log.info("物业公司{}综合统计信息获取成功", propertyCompanyId);
        return Result.success(stats);
    }


    /**
     * 更新物业公司信息
     * 
     * @param propertyCompanyId 物业公司ID
     * @param propertyInfoDTO 物业信息更新数据
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @PutMapping("/{propertyCompanyId}")
    @Operation(summary = "更新物业公司信息", description = "更新物业公司的基本信息")
    @ApiLog(
        logTitle = "更新物业公司信息",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.UPDATE
    )
    public Result<Boolean> updatePropertyInfo(
            @Parameter(description = "物业公司ID", required = true)
            @PathVariable @NotNull(message = "物业公司ID不能为空") 
            @Positive(message = "物业公司ID必须为正数") Long propertyCompanyId,
            @Parameter(description = "物业信息更新数据", required = true)
            @RequestBody @Valid PropertyInfoDTO propertyInfoDTO) throws Exception {
        log.info("开始更新物业公司信息，物业公司ID：{}，更新数据：{}", propertyCompanyId, propertyInfoDTO);
        
        // 权限验证
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            log.warn("用户未登录，无法更新物业公司{}信息", propertyCompanyId);
            return Result.fail("用户未登录，请先登录");
        }
        
        // 参数验证
        if (propertyInfoDTO == null) {
            log.warn("物业信息更新数据为空，物业公司ID：{}", propertyCompanyId);
            return Result.fail("更新数据不能为空");
        }
        
        // 设置物业公司ID
        propertyInfoDTO.setPropertyCompanyId(propertyCompanyId);
        
        // 调用Service层更新物业公司信息
        boolean success = propertyInfoService.updatePropertyInfo(propertyInfoDTO);
        
        if (success) {
            log.info("物业公司{}信息更新成功", propertyCompanyId);
            return Result.success("更新成功", true);
        } else {
            log.warn("物业公司{}信息更新失败", propertyCompanyId);
            return Result.fail("更新失败，请检查数据");
        }
    }



    /**
     * 获取物业公司统计信息
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 统计信息
     * @throws Exception 统一异常
     */
    @GetMapping("/statistics/{propertyCompanyId}")
    @Operation(summary = "获取物业公司统计信息", description = "获取指定物业公司的统计信息")
    public Result<PropertyInfoStatsVO> getPropertyCompanyStatistics(
            @Parameter(description = "物业公司ID", required = true)
            @PathVariable @NotNull(message = "物业公司ID不能为空") 
            @Positive(message = "物业公司ID必须为正数") Long propertyCompanyId) throws Exception {
        log.info("开始获取物业公司{}统计信息", propertyCompanyId);
        
        PropertyInfoStatsVO statistics = propertyInfoService.getPropertyInfoStats(propertyCompanyId);
        
        log.info("物业公司{}统计信息获取成功", propertyCompanyId);
        return Result.success(statistics);
    }
}
